﻿using IBatisNet.Common.Utilities;
using IBatisNet.DataMapper;
using IBatisNet.DataMapper.Configuration;
using System;
using System.Collections.Specialized;
using System.IO;
using System.Xml;

namespace NoteHelper.Business.IbatisImpl
{
    public class SqliteMapper
    {
        private static volatile ISqlMapper _mapper = null;
        private static object obj = new object();
        private const string DesKey = "cyandczx";// 加密密钥

        public static ISqlMapper Instance()
        {
            if (_mapper == null)
            {
                lock (obj)
                {
                    if (_mapper == null) // double-check
                    {
                        InitMapper();
                    }
                }
            }
            return _mapper;
        }

        public static void SetDbFile(string dbFile)
        {
            CreateIfNotExists();
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(ConfigFile);
            string xPath = "/setups/database/dbserver";
            var node = xmlDoc.SelectSingleNode(xPath);

            if (node != null)
            {
                node.InnerText = DesEncrypt.Encrypt(dbFile);
                xmlDoc.Save(ConfigFile);
            }
            _mapper = null;
        }

        public static string GetDbFilePath()
        {
            CreateIfNotExists();
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(ConfigFile);
            string xPath = "/setups/database/dbserver";
            var node = xmlDoc.SelectSingleNode(xPath);
            if (node == null)
                throw new Exception(string.Format("配置文件找不到 {0}", xPath));
            return DesEncrypt.Decrypt(node.InnerText);
        }

        #region 私有方法

        private static string ConfigFile
        {
            get { return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CfgFiles/Config.xml"); }
        }

        private static void Configure(object resource)
        {
            _mapper = null;
        }

        private static void InitMapper()
        {
            ConfigureHandler handler = new ConfigureHandler(Configure);
            DomSqlMapBuilder builder = new DomSqlMapBuilder();
            NameValueCollection properties = new NameValueCollection
            {
                {"connectionString", "Data Source=" + GetDbFilePath()}
            };
            builder.Properties = properties;
            FileInfo resource = new FileInfo("CfgFiles/SqliteMap.config");
            _mapper = builder.ConfigureAndWatch(resource, handler);
        }

        private static void CreateIfNotExists()
        {
            DesEncrypt.KeyCode = DesKey;
            var doc = new XmlDocument();
            if (!File.Exists(ConfigFile))
            {
                //创建Xml声明部分，即<?xml version="1.0" encoding="utf-8" ?>
                doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));
                //创建根节点
                XmlNode rootNode = doc.CreateElement("setups");

                //创建dbNode子节点
                XmlNode dbNode = doc.CreateElement("database");
                XmlNode node = doc.CreateElement("dbserver");
                node.InnerText = DesEncrypt.Encrypt("CfgFiles/dmdata.db3");
                dbNode.AppendChild(node);
                XmlNode uidNode = doc.CreateElement("uid");
                uidNode.InnerText = "sa";
                dbNode.AppendChild(uidNode);
                XmlNode pwdNode = doc.CreateElement("pwd");
                pwdNode.InnerText = DesEncrypt.Encrypt("polytech");
                dbNode.AppendChild(pwdNode);

                rootNode.AppendChild(dbNode);
                doc.AppendChild(rootNode);
                doc.Save(ConfigFile);
            }
        }

        #endregion
    }
}
